﻿using System;
using System.Collections.Generic;
using System.IO;
using GarageGames.Torque.Core;
using GarageGames.Torque.MathUtil;
using GarageGames.Torque.SceneGraph;
using GarageGames.Torque.Sim;
using GarageGames.Torque.T3D.RigidCollision;
using GarageGames.Torque.TS;
using GarageGames.Torque.Materials;
using GarageGames.Torque.Util;
using GarageGames.Torque.XNA;
using GarageGames.Torque.RenderManager;
using GarageGames.Torque.GFX;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;



namespace GarageGames.Torque.T3D
{
    //randomly scatters vegetation billboards 
    public class XTerrainBillboards : TorqueObject
    {

        #region Public properties, operators, constants, and enums

        public TorqueObject BillboardTemplate
        {
            get;
            set;
        }



        public float SpreadRadius
        {
            get;
            set;
        }



        public bool DropToTerrain
        {
            get;
            set;
        }



        public int Quantity
        {
            get;
            set;
        }

        #endregion


        public override bool OnRegister()
        {
            TorqueObject billboardClone;

            for (int index = 0; index < Quantity; index++)
            {
                billboardClone = (TorqueObject)BillboardTemplate.Clone();

                T3DSceneComponent veggieSceneComponent = Components.FindComponent<T3DSceneComponent>();
                T3DSceneComponent templateSceneComponent = billboardClone.Components.FindComponent<T3DSceneComponent>();

                if (veggieSceneComponent != null && templateSceneComponent != null)
                {
                    templateSceneComponent.Position = veggieSceneComponent.Position;
                    templateSceneComponent.Position += new Vector3(
                        TorqueUtil.GetFastRandomFloat(-1 * SpreadRadius, SpreadRadius),
                        TorqueUtil.GetFastRandomFloat(-1 * SpreadRadius, SpreadRadius),
                        0);

                    if (DropToTerrain)
                        MoveSelectedObjectToGround(billboardClone, billboardClone.Components.FindComponent<T3DBillboardRenderComponent>().Height);
                }

                TorqueObjectDatabase.Instance.Register(billboardClone);
            }

            return base.OnRegister();
        }



        public void MoveSelectedObjectToGround(TorqueObject obj, float ObjectHeight)
        {
            T3DSceneComponent componentScene = obj.Components.FindComponent<T3DSceneComponent>();

            if (componentScene != null)
            {
                Vector3 positionObject = componentScene.Position;

                XTerrain terrain = TorqueObjectDatabase.Instance.FindObject<XTerrain>();

                if (terrain != null)
                {
                    TorqueObjectType groundObjectType = TorqueObjectType.NoObjects;
                    groundObjectType += TorqueObjectDatabase.Instance.GetObjectType("Terrain") + TorqueObjectDatabase.Instance.GetObjectType("StaticGeometry");

                    RayCastQueryData _rayCast = new RayCastQueryData();
                    _rayCast.Position = positionObject;
                    _rayCast.Direction = new Vector3(0, 0, -1);
                    _rayCast.Length = 1000; // groundTolerance * 2.0f;
                    _rayCast.IgnoreObject = componentScene.Owner;

                    RigidCollisionManager manager = TorqueObjectDatabase.Instance.FindObject<RigidCollisionManager>();
                    manager.CollisionScene.CastRay(_rayCast);

                    if (_rayCast.Intersection != Vector3.Zero)
                    {
                        componentScene.Position = _rayCast.Intersection;
                        componentScene.Position += new Vector3(ObjectHeight / 2);
                    }
                    else
                    {
                        //maybe object is below terrain
                        _rayCast.Direction = new Vector3(0, 0, 1);
                        manager.CollisionScene.CastRay(_rayCast);

                        if (_rayCast.Intersection != Vector3.Zero)
                        {
                            componentScene.Position = _rayCast.Intersection;
                        }
                    }
                }
            }

            return;
        }


    }
}
